<!DOCTYPE HTML>
<html lang="zh-Hans" class="sidebar-visible no-js light">
    <head>
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>Rust Concept Clarification Deref vs AsRef vs Borrow vs Cow - Rust 优秀博文</title>


        <!-- Custom HTML head -->
        
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff" />

        <link rel="icon" href="../../favicon.svg">
        <link rel="shortcut icon" href="../../favicon.png">
        <link rel="stylesheet" href="../../css/variables.css">
        <link rel="stylesheet" href="../../css/general.css">
        <link rel="stylesheet" href="../../css/chrome.css">
        <link rel="stylesheet" href="../../css/print.css" media="print">

        <!-- Fonts -->
        <link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
        <link rel="stylesheet" href="../../fonts/fonts.css">

        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="../../highlight.css">
        <link rel="stylesheet" href="../../tomorrow-night.css">
        <link rel="stylesheet" href="../../ayu-highlight.css">

        <!-- Custom theme stylesheets -->

    </head>
    <body>
        <!-- Provide site root to javascript -->
        <script type="text/javascript">
            var path_to_root = "../../";
            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script type="text/javascript">
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script type="text/javascript">
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            var html = document.querySelector('html');
            html.classList.remove('no-js')
            html.classList.remove('light')
            html.classList.add(theme);
            html.classList.add('js');
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script type="text/javascript">
            var html = document.querySelector('html');
            var sidebar = 'hidden';
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            }
            html.classList.remove('sidebar-visible');
            html.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                <ol class="chapter"><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">1.</strong> 类型系统</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../01_类型系统/Rust_Concept_Clarification_Deref_vs_AsRef_vs_Borrow_vs_Cow/Rust_Concept_Clarification_Deref_vs_AsRef_vs_Borrow_vs_Cow.html" class="active"><strong aria-hidden="true">1.1.</strong> Rust Concept Clarification Deref vs AsRef vs Borrow vs Cow</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust_Concept_Clarification_Deref_vs_AsRef_vs_Borrow_vs_Cow/Deref_AsRef_Borrow_Cow释义.html"><strong aria-hidden="true">1.2.</strong> Deref AsRef Borrow Cow 释义</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust的Borrow和AsRef：让你的代码用起来像呼吸一样自然/Rust的Borrow和AsRef：让你的代码用起来像呼吸一样自然.html"><strong aria-hidden="true">1.3.</strong> Rust的Borrow和AsRef：让你的代码用起来像呼吸一样自然</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust的Cow类型有什么用？详解Cow及其用途/Rust的Cow类型有什么用？详解Cow及其用途.html"><strong aria-hidden="true">1.4.</strong> Rust的Cow类型有什么用？详解Cow及其用途</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/判别Fn、FnMut、FnOnce的标准/判别Fn、FnMut、FnOnce的标准.html"><strong aria-hidden="true">1.5.</strong> 判别Fn、FnMut、FnOnce的标准</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/一行代码告诉你内部可变性的真相(UnsafeCell)/一行代码告诉你内部可变性的真相(UnsafeCell).html"><strong aria-hidden="true">1.6.</strong> 一行代码告诉你内部可变性的真相(UnsafeCell)</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Tour_of_Rust's_Standard_Library_Traits/Tour_of_Rust's_Standard_Library_Traits.html"><strong aria-hidden="true">1.7.</strong> Tour of Rust's Standard Library Traits</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/逆变、协变与子类型，以及Rust/逆变、协变与子类型，以及Rust.html"><strong aria-hidden="true">1.8.</strong> 逆变、协变与子类型，以及Rust</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust自引用结构、Pin与Unpin/Rust自引用结构、Pin与Unpin.html"><strong aria-hidden="true">1.9.</strong> Rust自引用结构、Pin与Unpin</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/为什么Rust需要Pin,Unpin/为什么Rust需要Pin,Unpin.html"><strong aria-hidden="true">1.10.</strong> 译：为什么 Rust 需要 Pin, Unpin ？</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/定海神针Pin和Unpin/定海神针Pin和Unpin.html"><strong aria-hidden="true">1.11.</strong> 译：定海神针 Pin 和 Unpin</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/sizedness-in-rust/sizedness-in-rust.html"><strong aria-hidden="true">1.12.</strong> Sizedness in Rust</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/Rust生命周期集大成者PhantomData〈T〉/Rust生命周期集大成者PhantomData〈T〉.html"><strong aria-hidden="true">1.13.</strong> Rust生命周期集大成者 PhantomData&lt;T&gt;</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：用Rust做类型体操_Part_0.html"><strong aria-hidden="true">1.14.</strong> 数据库表达式执行的黑魔法：用Rust做类型体操 Part 0</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：GAT实现引用类型关联_Part_1.html"><strong aria-hidden="true">1.15.</strong> 数据库表达式执行的黑魔法：GAT实现引用类型关联 Part 1</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：用HRTB写bound_Part_2.html"><strong aria-hidden="true">1.16.</strong> 数据库表达式执行的黑魔法：用HRTB写bound Part 2</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：用Rust做类型体操之用宏展开重复代码_Part_3_&_4.html"><strong aria-hidden="true">1.17.</strong> 数据库表达式执行的黑魔法：用Rust做类型体操之用宏展开重复代码 Part 3 & 4</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：与Rust编译器斗智斗勇之表达式向量化_Part_5_&_6.html"><strong aria-hidden="true">1.18.</strong> 数据库表达式执行的黑魔法：与Rust编译器斗智斗勇之表达式向量化 Part 5 & 6</a></li><li class="chapter-item expanded "><a href="../../01_类型系统/数据库表达式执行的黑魔法：用Rust做类型体操/数据库表达式执行的黑魔法：在Rust中用宏关联逻辑类型和实际类型_Part_7.html"><strong aria-hidden="true">1.19.</strong> 数据库表达式执行的黑魔法：在Rust中用宏关联逻辑类型和实际类型 Part 7</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">2.</strong> 生命周期</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../02_生命周期/Rust中的生命周期——从StrSplit实例说开去/Rust中的生命周期——从StrSplit实例说开去.html"><strong aria-hidden="true">2.1.</strong> Rust中的生命周期——从StrSplit实例说开去</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/与ChatGPT深度对话来学Rust生命周期/与ChatGPT深度对话来学Rust生命周期.html"><strong aria-hidden="true">2.2.</strong> 与ChatGPT深度对话来学Rust生命周期</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/进击的Rust生命周期——early_bound与late_bound（1）/进击的Rust生命周期——early_bound与late_bound（1）.html"><strong aria-hidden="true">2.3.</strong> 进击的Rust生命周期——early_bound与late_bound（1）</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/进击的Rust生命周期——early_bound与late_bound（2）/进击的Rust生命周期——early_bound与late_bound（2）.html"><strong aria-hidden="true">2.4.</strong> 进击的Rust生命周期——early_bound与late_bound（2）</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/进击的Rust生命周期——一力降十会的MIR（1）/进击的Rust生命周期——一力降十会的MIR（1）.html"><strong aria-hidden="true">2.5.</strong> 进击的Rust生命周期——一力降十会的MIR（1）</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/进击的Rust生命周期——一力降十会的MIR（2）/进击的Rust生命周期——一力降十会的MIR（2）.html"><strong aria-hidden="true">2.6.</strong> 进击的Rust生命周期——一力降十会的MIR（2）</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/Common_Rust_Lifetime_Misconceptions/Common_Rust_Lifetime_Misconceptions.html"><strong aria-hidden="true">2.7.</strong> Common Rust Lifetime Misconceptions</a></li><li class="chapter-item expanded "><a href="../../02_生命周期/Rust生命周期常见误区/Rust生命周期常见误区.html"><strong aria-hidden="true">2.8.</strong> 译：Rust生命周期常见误区</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">3.</strong> 无畏并发</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../05_无畏并发/简单写个Rust无锁队列/简单写个Rust无锁队列.html"><strong aria-hidden="true">3.1.</strong> 简单写个Rust无锁队列</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/进击的Rust多线程——混合自旋锁/进击的Rust多线程——混合自旋锁.html"><strong aria-hidden="true">3.2.</strong> 进击的Rust多线程——混合自旋锁</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/An_unsafe_tour_of_Rust's_Send_and_Sync/An_unsafe_tour_of_Rust's_Send_and_Sync.html"><strong aria-hidden="true">3.3.</strong> An unsafe tour of Rust's Send and Sync</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/进击的Rust多线程——Send与Sync/进击的Rust多线程——Send与Sync.html"><strong aria-hidden="true">3.4.</strong> 进击的Rust多线程——Send与Sync</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/进击的Rust多线程——离经叛道的PhantomData/进击的Rust多线程——离经叛道的PhantomData.html"><strong aria-hidden="true">3.5.</strong> 进击的Rust多线程——离经叛道的PhantomData</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/Rust_Async_Pin概念解析/Rust_Async_Pin概念解析.html"><strong aria-hidden="true">3.6.</strong> Rust Async: Pin概念解析</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/Rust和C++的并发库对比/Rust和C++的并发库对比.html"><strong aria-hidden="true">3.7.</strong> 译：Rust 和 C++ 的并发库对比</a></li><li class="chapter-item expanded "><a href="../../05_无畏并发/Rust原子类型和内存排序/Rust原子类型和内存排序.html"><strong aria-hidden="true">3.8.</strong> Rust原子类型和内存排序</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">4.</strong> 网络编程</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../06_网络编程/从编解码层面理解WebSocket_手写一个WebSocket/从编解码层面理解WebSocket_手写一个WebSocket.html"><strong aria-hidden="true">4.1.</strong> 从编解码层面理解WebSocket 手写一 个WebSocket</a></li><li class="chapter-item expanded "><a href="../../06_网络编程/透过Rust探索系统的本原：网络篇/透过Rust探索系统的本原：网络篇.html"><strong aria-hidden="true">4.2.</strong> 透过Rust探索系统的本原：网络篇</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">5.</strong> 轮子系列</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../07_轮子系列/700行Rust写一个内存分配器/700行Rust写一个内存分配器.html"><strong aria-hidden="true">5.1.</strong> 700行Rust写一个内存分配器</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/Rust：网络库的实现思路/Rust：网络库的实现思路.html"><strong aria-hidden="true">5.2.</strong> Rust：网络库的实现思路</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/Rust异步运行时基础部件/Rust异步运行时基础部件.html"><strong aria-hidden="true">5.3.</strong> Rust异步运行时基础部件</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/使用Rust+epoll编写异步IO框架/使用Rust+epoll编写异步IO框架（1）.html"><strong aria-hidden="true">5.4.</strong> 使用Rust+epoll编写异步IO框架（1）</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/使用Rust+epoll编写异步IO框架/使用Rust+epoll编写异步IO框架（2）.html"><strong aria-hidden="true">5.5.</strong> 使用Rust+epoll编写异步IO框架（2）</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/使用Rust+epoll编写异步IO框架/使用Rust+epoll编写异步IO框架（3）.html"><strong aria-hidden="true">5.6.</strong> 使用Rust+epoll编写异步IO框架（3）</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day1.html"><strong aria-hidden="true">5.7.</strong> 用rust从零开发一套web框架：day1</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day2.html"><strong aria-hidden="true">5.8.</strong> 用rust从零开发一套web框架：day2</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day3.html"><strong aria-hidden="true">5.9.</strong> 用rust从零开发一套web框架：day3</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day4.html"><strong aria-hidden="true">5.10.</strong> 用rust从零开发一套web框架：day4</a></li><li class="chapter-item expanded "><a href="../../07_轮子系列/用rust从零开发一套web框架/用rust从零开发一套web框架：day5.html"><strong aria-hidden="true">5.11.</strong> 用rust从零开发一套web框架：day5</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">6.</strong> 奇技淫巧</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../08_奇技淫巧/Copy-On-Write是不是优化？/Copy-On-Write是不是优化？.html"><strong aria-hidden="true">6.1.</strong> 译：Copy-On-Write是不是优化？</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/揭秘神奇的Rust_Axum风格的函数实现/揭秘神奇的Rust_Axum风格的函数实现.html"><strong aria-hidden="true">6.2.</strong> 译：揭秘神奇的 Rust Axum 风格的函数实现</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/“变长参数”函数与回调/“变长参数”函数与回调.html"><strong aria-hidden="true">6.3.</strong> “变长参数”函数与回调</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/Rust字符串格式化的幕后：format_args!()/Rust字符串格式化的幕后：format_args!().html"><strong aria-hidden="true">6.4.</strong> 译：Rust字符串格式化的幕后：format_args!()</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/给Rust带来一点C++特产/给Rust带来一点C++特产.html"><strong aria-hidden="true">6.5.</strong> 给Rust带来一点C++特产</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/一步步实现_Rust_Bevy_ECS_的_System_简化版本/一步步实现_Rust_Bevy_ECS_的_System_简化版本.html"><strong aria-hidden="true">6.6.</strong> 一步步实现 Rust Bevy ECS 的 System 简化版本</a></li><li class="chapter-item expanded "><a href="../../08_奇技淫巧/Exploring_Design_Patterns_in_Rust_with_Algorithmic_Trading_Examples/Exploring_Design_Patterns_in_Rust_with_Algorithmic_Trading_Examples.html"><strong aria-hidden="true">6.7.</strong> Exploring Design Patterns in Rust with Algorithmic Trading Examples</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">7.</strong> 源码分析</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../09_源码分析/Rust并发：bytes源码分析/Rust并发：bytes源码分析.html"><strong aria-hidden="true">7.1.</strong> Rust并发：bytes源码分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust并发：标准库Arc源码分析/Rust并发：标准库Arc源码分析.html"><strong aria-hidden="true">7.2.</strong> Rust并发：标准库Arc源码分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust并发：标准库sync_Once源码分析/Rust并发：标准库sync_Once源码分析.html"><strong aria-hidden="true">7.3.</strong> Rust并发：标准库sync::Once源码分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust源码阅读：引用计数Rc/Rust源码阅读：引用计数Rc.html"><strong aria-hidden="true">7.4.</strong> Rust源码阅读：引用计数Rc</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust源码阅读：Cell、RefCell与内部可变性/Rust源码阅读：Cell、RefCell与内部可变性.html"><strong aria-hidden="true">7.5.</strong> Rust源码阅读： Cell、RefCell与内部可变性</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/关于_Rust_的_UnsafeCell、Cell_与_RefCell/关于_Rust_的_UnsafeCell、Cell_与_RefCell.html"><strong aria-hidden="true">7.6.</strong> 关于 Rust 的 UnsafeCell、Cell 与 RefCell</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust_Async_async-stream源码分析/Rust_Async_async-stream源码分析.html"><strong aria-hidden="true">7.7.</strong> Rust Async: async-stream源码分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/走进Tokio的异步世界/走进Tokio的异步世界.html"><strong aria-hidden="true">7.8.</strong> 走进 Tokio 的异步世界</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/tokio.rs_runtime的实现/tokio.rs_runtime的实现.html"><strong aria-hidden="true">7.9.</strong> tokio.rs runtime 的实现</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Tokio_internals/Tokio_internals.html"><strong aria-hidden="true">7.10.</strong> Tokio internals</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Tokio_internals/译文：Tokio內部机制.html"><strong aria-hidden="true">7.11.</strong> 译：Tokio 内部机制</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Rust_Axum_HTTP_框架的架构分析/Rust_Axum_HTTP_框架的架构分析.html"><strong aria-hidden="true">7.12.</strong> Rust Axum HTTP 框架的架构分析</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/安利一个Rust_Game_Engine：Bevy--ECS部分/安利一个Rust_Game_Engine：Bevy--ECS部分.html"><strong aria-hidden="true">7.13.</strong> 安利一个Rust Game Engine：Bevy--ECS部分</a></li><li class="chapter-item expanded "><a href="../../09_源码分析/Tokio_解析之任务调度/Tokio_解析之任务调度.html"><strong aria-hidden="true">7.14.</strong> Tokio 解析之任务调度</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">8.</strong> 生态观察</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../11_生态观察/Rust_web_frameworks_have_subpar_error_reporting/Rust_web_frameworks_have_subpar_error_reporting.html"><strong aria-hidden="true">8.1.</strong> Rust web frameworks have subpar error reporting</a></li><li class="chapter-item expanded "><a href="../../11_生态观察/SeaORM：要做Rust版本的ActiveRecord/SeaORM：要做Rust版本的ActiveRecord.html"><strong aria-hidden="true">8.2.</strong> SeaORM：要做Rust版本的ActiveRecord</a></li></ol></li><li class="chapter-item expanded "><a href="../../empty.html"><strong aria-hidden="true">9.</strong> 死灵终极</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_总述.html"><strong aria-hidden="true">9.1.</strong> 译：Learn Rust the Dangerous Way 总述</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_0.html"><strong aria-hidden="true">9.2.</strong> 译：Learn Rust the Dangerous Way 0</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_1.html"><strong aria-hidden="true">9.3.</strong> 译：Learn Rust the Dangerous Way 1</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_2.html"><strong aria-hidden="true">9.4.</strong> 译：Learn Rust the Dangerous Way 2</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_3.html"><strong aria-hidden="true">9.5.</strong> 译：Learn Rust the Dangerous Way 3</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_4.html"><strong aria-hidden="true">9.6.</strong> 译：Learn Rust the Dangerous Way 4</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Learn_Rust_the_Dangerous_Way_系列文章翻译/Learn_Rust_the_Dangerous_Way_系列文章翻译_5.html"><strong aria-hidden="true">9.7.</strong> 译：Learn Rust the Dangerous Way 5</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Unsafe_Rust_随堂小测/Unsafe_Rust_随堂小测（一）.html"><strong aria-hidden="true">9.8.</strong> Unsafe Rust 随堂小测（一）</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Unsafe_Rust_随堂小测/Unsafe_Rust_随堂小测（二）.html"><strong aria-hidden="true">9.9.</strong> Unsafe Rust 随堂小测（二）</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Unsafe_Rust_随堂小测/Unsafe_Rust_随堂小测（三）.html"><strong aria-hidden="true">9.10.</strong> Unsafe Rust 随堂小测（三）</a></li><li class="chapter-item expanded "><a href="../../12_死灵终极/Unsafe_Rust_随堂小测/Unsafe_Rust_随堂小测参考答案.html"><strong aria-hidden="true">9.11.</strong> Unsafe Rust 随堂小测参考答案</a></li></ol></li></ol>
            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
        </nav>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky bordered">
                    <div class="left-buttons">
                        <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </button>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>

                    <h1 class="menu-title">Rust 优秀博文</h1>

                    <div class="right-buttons">
                        <a href="../../print.html" title="Print this book" aria-label="Print this book">
                            <i id="print-button" class="fa fa-print"></i>
                        </a>

                    </div>
                </div>

                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>

                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script type="text/javascript">
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <h1 id="rust-concept-clarification-deref-vs-asref-vs-borrow-vs-cow"><a class="header" href="#rust-concept-clarification-deref-vs-asref-vs-borrow-vs-cow">Rust Concept Clarification: Deref vs AsRef vs Borrow vs Cow</a></h1>
<p>作者：<a href="https://dev.to/zhanghandong">HanDong Zhang</a></p>
<p>原载：<a href="https://dev.to/zhanghandong/rust-concept-clarification-deref-vs-asref-vs-borrow-vs-cow-13g6">https://dev.to/zhanghandong/rust-concept-clarification-deref-vs-asref-vs-borrow-vs-cow-13g6</a></p>
<h2 id="understanding-by-module"><a class="header" href="#understanding-by-module">Understanding by Module</a></h2>
<p>In fact, the classification by standard library will first give you a small idea of what they do.</p>
<ol>
<li><a href="https://doc.rust-lang.org/std/index.html">std</a>::<a href="https://doc.rust-lang.org/std/ops/index.html">ops</a>::<a href="https://doc.rust-lang.org/std/ops/trait.Deref.html">Deref</a> . As you can see, <code>Deref</code> is categorized as an <code>ops</code> module. If you look at the documentation, you will see that this module defines the <a href="https://doc.rust-lang.org/std/ops/index.html#traits">trait</a> fr all the overloadable operators. For example, <code>Add trait</code> corresponds to <code>+</code>, while <code>Deref trait</code> corresponds to a shared(immutable) borrowing dereference operation, such as <code>*v</code> . Correspondingly, there is also the <code>DerefMut trait</code>， which corresponds to the dereferencing operation of exclusive(mutable) borrowing. Since the Rust ownership semantics is a language feature throughout , the semantics of <code>Owner</code> / <code>immutable borrowing(&amp;T)</code>/ <code>mutable borrowing(&amp;mut T)</code> all appear together.</li>
<li><a href="https://doc.rust-lang.org/std/index.html">std</a>::<a href="https://doc.rust-lang.org/std/convert/index.html">convert</a>::<a href="https://doc.rust-lang.org/std/convert/trait.AsRef.html">AsRef</a> . As you can see, <code>AsRef</code> is grouped under the convert module. if you look at the documentation, you will see that <a href="https://doc.rust-lang.org/std/convert/index.html#traits">traits</a> related to type conversions are defined in this module. For example, the familiar &quot;From/To&quot;, &quot;TryFrom/TryTo&quot; and &quot;AsRef/AsMut&quot; also appear in pairs here, indicating that the feature is releated to type conversions. Based on the naming rules in the <a href="https://rust-lang.github.io/api-guidelines/">Rust API Guidelines</a> , wen can infer that methods starting with <code>as_</code> represent conversions from <code>borrow -&gt; borrow</code>, i.e, <code>reference -&gt; reference</code> , and are overhead-free. And such conversions do not fail.</li>
<li><a href="https://doc.rust-lang.org/std/index.html">std</a>::<a href="https://doc.rust-lang.org/std/borrow/index.html">borrow</a>::<a href="https://doc.rust-lang.org/std/borrow/trait.Borrow.html">Borrow</a>. As you can see, <code>Borrow</code> is categorized in the borrow module. The documentation for this module is very minimal, with a single sentence saying that this is for using borrowed data. So the trait is more or less related to expressing borrwo semantics. Three <a href="https://doc.rust-lang.org/std/borrow/index.html#traits">traits</a> are provided: <a href="https://doc.rust-lang.org/std/borrow/trait.Borrow.html">Borrow</a> / <a href="https://doc.rust-lang.org/std/borrow/trait.BorrowMut.html">BorrowMut</a>/ <a href="https://doc.rust-lang.org/std/borrow/trait.ToOwned.html">ToOwned</a> , which corresponds exactly to the ownership semantics.</li>
<li><a href="https://doc.rust-lang.org/std/index.html">std</a>::<a href="https://doc.rust-lang.org/std/borrow/index.html">borrow</a>::<a href="https://doc.rust-lang.org/std/borrow/enum.Cow.html">Cow</a>. It can be seen that <code>Cow</code> is also classified as a borrow module. According to the description, <code>Cow</code> is a clone-on-write smart pointer. The main reason for putting it in the borrow module is to use borrowing as much as possible and avoid copying, as an optimization.</li>
</ol>
<h2 id="stdopsderef"><a class="header" href="#stdopsderef"><a href="https://doc.rust-lang.org/std/index.html">std</a>::<a href="https://doc.rust-lang.org/std/ops/index.html">ops</a>::<a href="https://doc.rust-lang.org/std/ops/trait.Deref.html">Deref</a></a></h2>
<p>First, let's look at the definition of the trait.</p>
<pre><code>pub trait Deref {
    type Target: ?Sized;
    #[must_use]
    pub fn deref(&amp;self) -&gt; &amp;Self::Target;
}
</code></pre>
<p>The definition is not complicated, <code>Deref</code> contains only a <code>deref</code> method signature. The beauty of this trait is that it is called &quot;implicitly&quot; by the compiler, officially called &quot;<a href="https://doc.rust-lang.org/std/ops/trait.Deref.html#more-on-deref-coercion">deref coercion</a> &quot;.</p>
<p>Here is an example from the standard library.</p>
<pre><code>use std::ops::Deref;

struct DerefExample&lt;T&gt; {
    value: T
}

impl&lt;T&gt; Deref for DerefExample&lt;T&gt; {
    type Target = T;

    fn deref(&amp;self) -&gt; &amp;Self::Target {
        &amp;self.value
    }
}

let x = DerefExample { value: 'a' };
assert_eq!('a', *x);
</code></pre>
<p>In the code, the <code>DerefExample</code> structure implements the <code>Deref</code> trait, so it can be executed using the dereference operator <code>*</code>. In the example, the value of the field value is returned directly.</p>
<p>As you can see, <code>DerefExample</code> has a pointer-like behavior , because it implements <code>Deref</code>, because it can be dereferenced. <code>DerefExample</code> also becomes a kind of smart pointer. This is one way to identify if a type is a smart pointer, by seeing if it implements <code>Deref</code>. But not all smart pointers implement <code>Deref</code>, some implent <code>Drop</code>, or both.</p>
<p>Now let's summarize <code>Deref</code>.</p>
<p>If <code>T</code> implements <code>Deref&lt;Target=U&gt;</code>, and <code>x</code> is an instance of type <code>T</code>, then.</p>
<ol>
<li>In an immutable context, the operation of <code>*x</code> (when <code>T</code> is neither a reference nor a primitive pointer) is equivalent to <code>*Deref::deref(&amp;x)</code>.</li>
<li>The value of <code>&amp;T</code> is forced to be converted to the value of <code>&amp;U</code>. (deref coercion).</li>
<li><code>T</code> implements all the (immutable) methods of <code>U</code>.</li>
</ol>
<p>The beauty of <code>Deref</code> is that it enhances the Rust development experience. A typical example from the standard library is that <code>Vec&lt;T&gt;</code> shares all the methods of <code>slice</code> by implemented <code>Deref</code>.</p>
<pre><code>impl&lt;T, A: Allocator&gt; ops::Deref for Vec&lt;T, A&gt; {
    type Target = [T];

    fn deref(&amp;self) -&gt; &amp;[T] {
        unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
    }
}
</code></pre>
<p>For example, the simplest method, <code>len()</code>, is actually defined in the <a href="https://doc.rust-lang.org/std/primitive.slice.html"><code>slice</code> </a>module. In Rust, when executing <code>.</code> call, or at the function argument position, the compiler automatically performs the implicit act of deref coercion. so it is equivalent to <code>Vec&lt;T&gt;</code> having the <code>slice</code> method as well.</p>
<pre><code>fn main() {
    let a = vec![1, 2, 3];
    assert_eq!(a.len(), 3); // 当 a 调用 len() 的时候，发生 deref 强转
}
</code></pre>
<p>Implicit behavior in Rust is not common, but <code>Deref</code> is one of them, and its implicit coercion make smart pointers easy to use.</p>
<pre><code>fn main() {
    let h = Box::new(&quot;hello&quot;);
    assert_eq!(h.to_uppercase(), &quot;HELLO&quot;);
}
</code></pre>
<p>For example, if we manipulate <code>Box&lt;T&gt;</code> , instead of manually dereferencing <code>T</code> inside to manipulate it, as if the outer layer of <code>Box&lt;T&gt;</code> is transparent, we can manipulate T directly.</p>
<p>Another example.</p>
<pre><code>fn uppercase(s: &amp;str) -&gt; String {
    s.to_uppercase()
}

fn main() {
    let s = String::from(&quot;hello&quot;);
    assert_eq!(uppercase(&amp;s), &quot;HELLO&quot;);
}
</code></pre>
<p>The argument type of the <code>uppercase</code> method above is obviously <code>&amp;str</code>, but the actual type passed in the main function is <code>&amp;String</code>, so why does it compile successfully? It is because <code>String</code> implements<code>Deref</code>.</p>
<pre><code>impl ops::Deref for String {
    type Target = str;

    #[inline]
    fn deref(&amp;self) -&gt; &amp;str {
        unsafe { str::from_utf8_unchecked(&amp;self.vec) }
    }
}
</code></pre>
<p>That's the beauty of <code>Deref</code>. But some people may mistake it for inheritance. Big mistake.</p>
<p>This behavior seems a bit like inheritance, but please don't just use <code>Deref</code> to simulate inheritance.</p>
<h2 id="stdconvertasref"><a class="header" href="#stdconvertasref"><a href="https://doc.rust-lang.org/std/index.html">std</a>::<a href="https://doc.rust-lang.org/std/convert/index.html">convert</a>::<a href="https://doc.rust-lang.org/std/convert/trait.AsRef.html">AsRef</a></a></h2>
<p>Let's look at the definition of <code>AsRef</code>.</p>
<pre><code>pub trait AsRef&lt;T: ?Sized&gt; {
    fn as_ref(&amp;self) -&gt; &amp;T;
}
</code></pre>
<p>We already know that <code>AsRef</code> can be used for conversions. Compared to <code>Deref</code>, which has an implicit behavior, <code>AsRef</code> is an explicit conversion.</p>
<pre><code>fn is_hello&lt;T: AsRef&lt;str&gt;&gt;(s: T) {
   assert_eq!(&quot;hello&quot;, s.as_ref());
}

fn main() {
    let s = &quot;hello&quot;;
    is_hello(s);

    let s = &quot;hello&quot;.to_string();
    is_hello(s);
}
</code></pre>
<p>In the above example, the function of <code>is_hello</code> is a generic function. The conversion is achieved by qualifying <code>T: AsRef&lt;str&gt;</code> and using an explicit call like <code>s.as_ref()</code> inside the function. Either <code>String</code> or <code>str</code> actually implements the <code>AsRef</code> trait.</p>
<p>So now the question is, when do you use <code>AsRef</code>? Why not just use <code>&amp;T</code>?</p>
<p>Consider an example like this.</p>
<pre><code>pub struct Thing {
    name: String,
}

impl Thing {
    pub fn new(name: WhatTypeHere) -&gt; Self {
        Thing { name: name.some_conversion() }
}
</code></pre>
<p>In the above example, the <code>new</code> function name has the following options for the type parameter.</p>
<ol>
<li><code>&amp;str</code>. In this case, the caller needs to pass in a reference. But in order to convert to String, the called party (callee) needs to control its own memory allocation, and will have a copy.</li>
<li><code>String</code>. In this case, the caller is fine passing String, but if it is passing a reference, it is similar to case 1.</li>
<li><code>T: Into&lt;String&gt;</code>. In this case, the caller can pass <code>&amp;str</code> and <code>String</code>, but there will be memory allocation and copying during the type conversion as well.</li>
<li><code>T: AsRef&lt;str&gt;</code>. Same as case 3.</li>
<li><code>T: Into&lt;Cow&lt;'a, str&gt;&gt;</code>, where some allocations can be avoided. <code>Cow</code> will be described later.</li>
</ol>
<p>There is no one-size-fits-all answer to the question of when to use which type. Some people just like <code>&amp;str</code> and will use it no matter what. There are trade-offs here.</p>
<ol>
<li>On occasions when assignment and copying are less important, there is no need to make type signatures too complicated, just use <code>&amp;str</code>.</li>
<li>Some need to look at method definitions and whether they need to consume ownership, or return ownership or borrowing.</li>
<li>Some need to minimize assignment and copy, so it is necessary to use more complex type signatures, as in case 5.</li>
</ol>
<h2 id="application-of-deref-and-asref-in-api-design"><a class="header" href="#application-of-deref-and-asref-in-api-design">Application of Deref and AsRef in API design</a></h2>
<p>The <strong><a href="https://github.com/rustwasm/wasm-bindgen">wasm-bindgen</a></strong> library contains a component called <a href="https://github.com/rustwasm/wasm-bindgen/tree/"><strong>web-sys</strong></a>.</p>
<p>This component is the binding of Rust to the browser Web API. As such, web-sys makes it possible to manipulate the browser DOM with Rust code, fetch server data, draw graphics, handle audio and video, handle client-side storage, and more.</p>
<p>However, binding Web APIs with Rust is not that simple. For example, manipulating the DOM relies on JavaScript class inheritance, so web-sys must provide access to this inheritance hierarchy. In web-sys, access to this inheritance structure is provided using <code>Deref</code> and <code>AsRef</code>.</p>
<p><strong>Using Deref</strong></p>
<pre><code>let element: &amp;Element = ...;

element.append_child(..); // call a method on `Node`

method_expecting_a_node(&amp;element); // coerce to `&amp;Node` implicitly

let node: &amp;Node = &amp;element; // explicitly coerce to `&amp;Node`
</code></pre>
<p>If you have <code>web_sys::Element</code>, then you can get <code>web_sys::Node</code> implicitly by using deref.</p>
<p>The use of deref is mainly for API ergonomic reasons, to make it easy for developers to use the <code>.</code> operation to transparently use the parent class.</p>
<p><strong>Using AsRef</strong></p>
<p>A large number of <code>AsRef</code> conversions are also implemented in web-sys for various types.</p>
<pre><code>impl AsRef&lt;HtmlElement&gt; for HtmlAnchorElement
impl AsRef&lt;Element&gt; for HtmlAnchorElement
impl AsRef&lt;Node&gt; for HtmlAnchorElement
impl AsRef&lt;EventTarget&gt; for HtmlAnchorElement
impl AsRef&lt;Object&gt; for HtmlAnchorElement
impl AsRef&lt;JsValue&gt; for HtmlAnchorElement
</code></pre>
<p>A reference to a parent structure can be obtained by explicitly calling <code>.as_ref()</code>.</p>
<p>Deref focuses on implicitly and transparently using the parent structure, while AsRef focuses on explicitly obtaining a reference to the parent structure. This is a trade-off with a specific API design, rather than a mindless simulation of OOP inheritance.</p>
<p>Another example of using AsRef is the <a href="https://github.com/http-rs/http-types">http-types</a> library, which uses AsRef and AsMut to convert various types.</p>
<p>For example, Request is a combination of <code>Stream / headers/ URL</code>, so it implements <code>AsRef&lt;Url&gt;</code>, <code>AsRef&lt;Headers&gt;</code>, and <code>AsyncRead</code>. Similarly, Response is a combination of <code>Stream / headers/ Status Code</code>. So it implements <code>AsRef&lt;StatusCode&gt;</code>, <code>AsRef&lt;Headers&gt;</code>, and <code>AsyncRead</code>.</p>
<pre><code>fn forwarded_for(headers: impl AsRef&lt;http_types::Headers&gt;) {
    // get the X-forwarded-for header
}

// 所以，forwarded_for 可以方便处理 Request/ Response / Trailers 
let fwd1 = forwarded_for(&amp;req);
let fwd2 = forwarded_for(&amp;res);
let fwd3 = forwarded_for(&amp;trailers);
</code></pre>
<h2 id="stdborrowborrow"><a class="header" href="#stdborrowborrow"><a href="https://doc.rust-lang.org/std/index.html">std</a>::<a href="https://doc.rust-lang.org/std/borrow/index.html">borrow</a>::<a href="https://doc.rust-lang.org/std/borrow/trait.Borrow.html">Borrow</a></a></h2>
<p>Take a look at the definition of <code>Borrow</code>.</p>
<pre><code>pub trait Borrow&lt;Borrowed: ?Sized&gt; {
    fn borrow(&amp;self) -&gt; &amp;Borrowed;
}
</code></pre>
<p>Contrast <code>AsRef</code>:</p>
<pre><code>pub trait AsRef&lt;T: ?Sized&gt; {
    fn as_ref(&amp;self) -&gt; &amp;T;
}
</code></pre>
<p>Isn't this very similar? So, some people suggest that one of these two functions could be removed altogether. But in fact, there is a difference between Borrow and AsRef, and they both have their own uses.</p>
<p>The Borrow trait is used to represent borrowed data. the AsRef trait is used for type conversion. In Rust, it is common to provide different type representations for different use cases for different semantics.</p>
<p>A type provides a reference/borrow to <code>T</code> in the <code>borrow()</code> method by implementing <code>Borrow&lt;T&gt;</code>, expressing the semantics that it can be borrowed, rather than converted to some type <code>T</code>. A type can be freely borrowed as several different types, or it can be borrowed in a mutable way.</p>
<p>So how do you choose between Borrow and AsRef?</p>
<ul>
<li>Choose Borrow when you want to abstract different borrow types in a uniform way, or when you want to create a data structure that handles self-contained values (owned) and borrowed values (borrowed) in the same way.</li>
<li>When you want to convert a type directly to a reference and you are writing generic code, choose AsRef. simpler case.</li>
</ul>
<p>In fact, the HashMap example given in the standard library documentation explains this very well. Let me translate it for you.</p>
<p><code>HashMap&lt;K, V&gt;</code> stores key-value pairs, and its API should be able to retrieve the corresponding value in the HashMap properly using either the key's own value or its reference. Since the HashMap has to hash and compare keys, it must require that both the key's own value and the reference behave the same when hashed and compared.</p>
<pre><code>use std::borrow::Borrow;
use std::hash::Hash;

pub struct HashMap&lt;K, V&gt; {
    // fields omitted
}

impl&lt;K, V&gt; HashMap&lt;K, V&gt; {
    // The insert method uses the key's own value and takes ownership of it.
    pub fn insert(&amp;self, key: K, value: V) -&gt; Option&lt;V&gt;
    where K: Hash + Eq
    {
        // ...
    }

    // If you use the get method to get the corresponding value by key, you can use the reference of key, which is denoted by &amp;Q here
    // and requires Q to satisfy `Q: Hash + Eq + ?Sized`
    // As for K, it is expressed as a borrowed data of Q by `K: Borrow&lt;Q&gt;`.
    // So, the hash implementation of Q is required to be the same as K
    pub fn get&lt;Q&gt;(&amp;self, k: &amp;Q) -&gt; Option&lt;&amp;V&gt;
    where
        K: Borrow&lt;Q&gt;,
        Q: Hash + Eq + ?Sized
    {
        // ...
    }
}
</code></pre>
<p>Borrow is a bound on borrowed data and is used with additional traits, such as <code>Hash</code> and <code>Eq</code> in the example.</p>
<p>See another example.</p>
<pre><code>//  Can this structure be used as the key of a HashMap?
pub struct CaseInsensitiveString(String);

// It implements PartialEq without problems
impl PartialEq for CaseInsensitiveString {
    fn eq(&amp;self, other: &amp;Self) -&gt; bool {
        // Note that the comparison here is required to ignore ascii case
        self.0.eq_ignore_ascii_case(&amp;other.0)
    }
}

impl Eq for CaseInsensitiveString { }

// Implementing Hash is no problem
// But since PartialEq ignores case, the hash calculation must also ignore case
impl Hash for CaseInsensitiveString {
    fn hash&lt;H: Hasher&gt;(&amp;self, state: &amp;mut H) {
        for c in self.0.as_bytes() {
            c.to_ascii_lowercase().hash(state)
        }
    }
}
</code></pre>
<p>Can CaseInsensitiveString implement <code>Borrow&lt;str&gt;</code>?</p>
<p>Obviously, CaseInsensitiveString and str have different implementations of Hash. str does not ignore case. Therefore, <code>Borrow&lt;str&gt;</code> must not be implemented for CaseInsensitiveString, so CaseInsensitiveString cannot be used as a key for a HashMap. What happens if we force <code>Borrow&lt;str&gt;</code> to be used? It will fail due to case difference when determining the key.</p>
<p>But CaseInsensitiveString can be fully implemented as AsRef.</p>
<p>This is the difference between Borrow and AsRef. <code>Borrow</code> is a bit stricter and represents a completely different semantics than <code>AsRef</code>.</p>
<h2 id="stdborrowcow"><a class="header" href="#stdborrowcow"><a href="https://doc.rust-lang.org/std/index.html">std</a>::<a href="https://doc.rust-lang.org/std/borrow/index.html">borrow</a>::<a href="https://doc.rust-lang.org/std/borrow/enum.Cow.html">Cow</a></a></h2>
<p>Look at the definition of <code>Cow</code>.</p>
<pre><code>pub enum Cow&lt;'a, B&gt; 
where
    B: 'a + ToOwned + ?Sized, 
 {
    Borrowed(&amp;'a B),
    Owned(&lt;B as ToOwned&gt;::Owned),
}
</code></pre>
<p>As you can see, Cow is an enumeration. It is somewhat similar to Option, in that it represents one of two cases, Cow here means borrowed and self-owned, but only one of these cases can occur.</p>
<p>The main functions of Cow are:</p>
<ol>
<li>acts as a smart pointer, providing transparent immutable access to instances of this type (e.g. the original immutable methods of this type can be called directly, implementing Deref, but not DerefMut).</li>
<li>if there is a need to modify an instance of this type, or to gain ownership of an instance of this type, <code>Cow</code> provides methods to do cloning and avoid repeated cloning.</li>
</ol>
<p><code>Cow</code> is designed to improve performance (reduce replication) while increasing flexibility, because most of the time, business scenarios are read more and write less. With <code>Cow</code>, this can be achieved in a uniform, canonical form, where object replication is done only once when a write is needed. This may reduce the number of replications significantly.</p>
<p>It has the following key points to master.</p>
<ol>
<li>
<p><code>Cow&lt;T&gt;</code> can directly call the immutable methods of <code>T</code>, since <code>Cow</code>, an enumeration, implements <code>Deref</code>.</p>
</li>
<li>
<p>the</p>
<pre><code>.to_mut()
</code></pre>
<p>method can be used to obtain a mutable borrow with an ownership value when</p>
<pre><code>T
</code></pre>
<p>needs to be modified.</p>
<ol>
<li>note that a call to <code>.to_mut()</code> does not necessarily result in a Clone.</li>
<li>calling <code>.to_mut()</code> when ownership is already present is valid, but does not produce a new Clone.</li>
<li>multiple calls to <code>.to_mut()</code> will produce only one Clone.</li>
</ol>
</li>
<li>
<pre><code>.into_owned()
</code></pre>
<p>can be used to create a new owned object when</p>
<pre><code>T
</code></pre>
<p>needs to be modified, a process that often implies a memory copy and the creation of a new object.</p>
<ol>
<li>calling this operation will perform a Clone if the value in the previous <code>Cow</code> was in borrowed state.</li>
<li>this method, whose argument is of type <code>self</code>, will &quot;consume&quot; the original instance of that type, after which the life cycle of the original instance of that type will end, and cannot be called more than once on <code>Cow</code>.</li>
</ol>
</li>
</ol>
<p>Cow is used more often in API design.</p>
<pre><code>use std::borrow::Cow;

// Use Cow for the return value to avoid multiple copies
fn remove_spaces&lt;'a&gt;(input: &amp;'a str) -&gt; Cow&lt;'a, str&gt; {
    if input.contains(' ') {
        let mut buf = String::with_capacity(input.len());
        for c in input.chars() {
            if c != ' ' {
                buf.push(c);
            }
        }
        return Cow::Owned(buf);
    }
    return Cow::Borrowed(input);
}
</code></pre>
<p>Of course, when to use Cow comes back to the &quot;when to use <code>AsRef</code>&quot; discussion in our previous article, there are trade-offs and no one-size-fits-all standard answer.</p>
<h2 id="summary"><a class="header" href="#summary">Summary</a></h2>
<p>To understand the various types and traits in Rust, you need to take into account the ownership semantics and ponder the documentation and examples, which should be easy to understand. I don't know if reading this article has solved your doubts? Feel free to share your feedback.</p>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->
                            <a rel="prev" href="../../empty.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                                <i class="fa fa-angle-left"></i>
                            </a>

                            <a rel="next" href="../../01_类型系统/Rust_Concept_Clarification_Deref_vs_AsRef_vs_Borrow_vs_Cow/Deref_AsRef_Borrow_Cow释义.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                                <i class="fa fa-angle-right"></i>
                            </a>

                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">
                    <a rel="prev" href="../../empty.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>

                    <a rel="next" href="../../01_类型系统/Rust_Concept_Clarification_Deref_vs_AsRef_vs_Borrow_vs_Cow/Deref_AsRef_Borrow_Cow释义.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
            </nav>

        </div>




        <script type="text/javascript">
            window.playground_copyable = true;
        </script>


        <script src="../../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../../mark.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../../searcher.js" type="text/javascript" charset="utf-8"></script>

        <script src="../../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="../../highlight.js" type="text/javascript" charset="utf-8"></script>
        <script src="../../book.js" type="text/javascript" charset="utf-8"></script>

        <!-- Custom JS scripts -->


    </body>
</html>
